package com.ibm.spatiotemp.test.requestServer;

import java.io.IOException;

import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ibm.spatiotemp.datamodel.config.BackendServerManager;
import com.ibm.spatiotemp.datamodel.config.CacheServerManager;
import com.ibm.spatiotemp.datamodel.config.PubSubMeta;
import com.ibm.spatiotemp.server.config.LocalConfig;
import com.ibm.spatiotemp.test.requestServer.redis.RedisPubSub;
import com.ibm.spatiotemp.tools.jsonParser;
import com.ibm.spatiotemp.utils.StringEncoder;

/*a mocking restful server to send request and wait for response*/
/**
 * MockRestfulServer serves as a restful server to send request to the backend server
 * to handle request and return back response to it
 * @author xuxiaomin
 *
 */
public class MockRestfulServer {

	/*test sending some request for test server*/
	public static Logger logger = Logger.getLogger(MockRestfulServer.class);
	
	public static String buildrespTopic(){
		return "resp."+System.currentTimeMillis();
	}
	
	/**
	 * http://127.0.0.1:8080/demo/handlequeryservlet?tenantid=mocktenant&sourceid=mocksrc&start=2014-01-01T00:00:51&end=2014-01-01T00:01:11&sourceid=mocksrc&id=2&queryType=trajectory
	 * http://127.0.0.1:8080/demo/handlequeryservlet?tenantid=mocktenant&sourceid=mocksrc&start=2014-01-01T00:00:45&end=2014-01-01T00:01:05&sourceid=mocksrc&bboxRel=intersect&bbox=[140.323171,20.880869,160.323171,40.880869]&queryType=trajectory
	 * http://127.0.0.1:8080/demo/handlequeryservlet?tenantid=mocktenant&sourceid=mocksrc&sourceid=mocksrc&bbox=[139.658454,22.546554,159.658454,42.546554]&time=2014-01-01T00:00:39&queryType=position
	 * http://127.0.0.1:8080/demo/handlequeryservlet?tenantid=mocktenant&sourceid=mocksrc&start=2014-01-01T00:00:40&end=2014-01-01T00:01:00&sourceid=mocksrc&distance=5&id=2&position=[149.771018,32.072983]&queryType=firsttime

	 * @return
	 */
	public static ObjectNode makeRequest_Trajectory2(PubSubMeta pubsubserver){
		ObjectNode node = jsonParser.newObjectNode();

		ObjectNode para_node = jsonParser.newObjectNode();
		para_node.put("tenantid", "mocktenant");
		para_node.put("sourceid", "mocksrc");
		para_node.put("qtype", "trajectory");
		para_node.put("sessionid", "session_test");
		
		para_node.put("start", "2015-03-26T00:00:00");
		para_node.put("end",   "2015-03-27T00:00:00");
		para_node.put("bboxRel", "intersect");
		para_node.put("bbox", "[-140.323171,-20.880869,160.323171,50.880869]");
		
		jsonParser.SetKeyandValue(node, JsonObject.RequestTags[0], para_node);
		node.put(JsonObject.RequestTags[1], buildrespTopic());/*randomly generate a topic*/
		node.put(JsonObject.RequestTags[2], pubsubserver.getServerip());
		node.put(JsonObject.RequestTags[3], pubsubserver.getPort());
		return node;
	}
	
	public static ObjectNode makeRequest_Trajectory1(PubSubMeta pubsubserver){
		ObjectNode node = jsonParser.newObjectNode();

		ObjectNode para_node = jsonParser.newObjectNode();
		para_node.put("tenantid", "mocktenant");
		para_node.put("sourceid", "mocksrc");
		para_node.put("qtype", "trajectory");
		para_node.put("sessionid", "session_test");
		
		para_node.put("id", "1");
		para_node.put("start", "2015-03-26T00:00:00");
		para_node.put("end",   "2015-03-27T00:00:00");
		
		jsonParser.SetKeyandValue(node, JsonObject.RequestTags[0], para_node);
		node.put(JsonObject.RequestTags[1], buildrespTopic());/*randomly generate a topic*/
		node.put(JsonObject.RequestTags[2], pubsubserver.getServerip());
		node.put(JsonObject.RequestTags[3], pubsubserver.getPort());
		return node;
	}

	
	public String response2Request(PubSubMeta pubsubserv, ObjectNode request, boolean iscompressenabled) throws ClassNotFoundException, IOException
	{
		String targetip = pubsubserv.getServerip();
		String targetport = pubsubserv.getPort();
		RedisPubSub senderclient = new RedisPubSub();
		senderclient.init(targetip,targetport);

		
		String respip = request.get(JsonObject.RequestTags[2]).asText();
		String respport = request.get(JsonObject.RequestTags[3]).asText();
		String resptopic = request.get(JsonObject.RequestTags[1]).asText();
		
		RedisPubSub recclient = new RedisPubSub();
		recclient.init(respip, respport);
		recclient.subscribe(resptopic);
		
		senderclient.publish(LocalConfig.RequestTopic, request.toString());
			while(true)
			{
				String[] response = recclient.getMessage();
				if(response != null && response[1]!=null){
					if(iscompressenabled)
						return StringEncoder.decompress(LocalConfig.codecClassname, response[1]);
					else
						return response[1];
				}
			}
	}
	
	MockRestfulServer restpartmock;
	@Before
	public void init(){
		CacheServerManager.init("conf/redisservers.conf");
		BackendServerManager.init("conf/backendinit.conf");

		restpartmock = new MockRestfulServer();
		
	}
	
	@Test
	public void testTrajectoryQuery1() throws ClassNotFoundException, IOException{
		PubSubMeta pubsebserv = BackendServerManager.
				getPubSubMetaByTopic(com.ibm.spatiotemp.server.config.LocalConfig.
						RequestTopic);
		ObjectNode requestobj = makeRequest_Trajectory1(pubsebserv);
		String response = restpartmock.response2Request(pubsebserv, requestobj, LocalConfig.EnableCompression);
		logger.info(response.length());
	}
	
	@Test
	public void testTrajectoryQuery2() throws ClassNotFoundException, IOException{
		PubSubMeta pubsebserv = BackendServerManager.
				getPubSubMetaByTopic(com.ibm.spatiotemp.server.config.LocalConfig.
						RequestTopic);
		ObjectNode requestobj = makeRequest_Trajectory2(pubsebserv);
		String response = restpartmock.response2Request(pubsebserv, requestobj,LocalConfig.EnableCompression);
		logger.info(response.length());
	}
	

}
